package com.yansl.http.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.http.HttpMethod;

import com.yansl.http.handler.HttpCallHandler;
import com.yansl.http.intercepter.DefaultHttpIntercepter;
import com.yansl.http.intercepter.HttpIntercepter;
import com.yansl.http.model.HttpRequest;

import lombok.extern.slf4j.Slf4j;

/**
 * @description: Http处理类
 * @author: yansl.cn
 * @create: 2022-12-17 11:45
 */
@Slf4j
public class HttpHandler implements InvocationHandler, ApplicationContextAware, CommandLineRunner {
    private Class DEFAULTHTTPINTERCEPTER_CLASS = DefaultHttpIntercepter.class;
    private Map<Class, HttpIntercepter> HTTPINTERCEPTERS = new HashMap<>();
    private HttpIntercepter defaultHttpIntercepter;
    private ApplicationContext applicationContext;

    @Autowired
    private HttpCallHandler httpCallHandler;

    /**
     * 存放@URI注解方法《目录.类.方法，封装请求对象》
     */
    private static Map<String, HttpRequest> HTTPS = new HashMap<>();

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String classMethodName = method.getDeclaringClass().getName() + "." + method.getName();
        HttpRequest httpRequest = HTTPS.get(classMethodName);
        httpRequest.setHttpCallHandler(httpCallHandler);
        httpRequest.setHttpIntercepter(gettHttpIntercepter(httpRequest.getHttpIntercepterClass()));
        TransforRequestParse parse = new TransforRequestParse(httpRequest, args);
        return HttpMethod.GET == httpRequest.getHttpMethod() ? parse.transforGet() : parse.transforPost();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public static void setHttp(HttpRequest httpRequest) {
        if (HttpHandler.HTTPS.containsKey(httpRequest.getClassMethodName())) {
            throw new RuntimeException("不支持方法重载:" + httpRequest.getClassMethodName());
        }
        HttpHandler.HTTPS.put(httpRequest.getClassMethodName(), httpRequest);
    }

    /**
     * 获取拦截器
     * 
     * @param clazz
     * @return
     */
    private HttpIntercepter gettHttpIntercepter(Class clazz) {
        HttpIntercepter httpIntercepter = HTTPINTERCEPTERS.get(clazz);
        if (Objects.isNull(httpIntercepter)) {
            httpIntercepter = defaultHttpIntercepter;
        }
        return httpIntercepter;
    }

    @Override
    public void run(String... args) throws Exception {

        // 自定义拦截器
        Map<String, HttpIntercepter> httpIntercepterMap = applicationContext.getBeansOfType(HttpIntercepter.class);
        for (HttpIntercepter httpIntercepter : httpIntercepterMap.values()) {
            HTTPINTERCEPTERS.put(httpIntercepter.getHttpIntercepterClass(), httpIntercepter);
            if (DEFAULTHTTPINTERCEPTER_CLASS == httpIntercepter.getHttpIntercepterClass()) {
                defaultHttpIntercepter = httpIntercepter;
            }
        }
    }
}
